home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
HENSA
/
GRAPHICS
/
SPRite_TOOLS.ARC
/
c
/
io
< prev
next >
Wrap
Text File
|
1998-04-07
|
13KB
|
462 lines
/****************************************************************************
* *
* io.c *
* ==== *
* *
* I/O routines for image format conversion programs *
* *
* Version 1.00 (13-Aug-1993) *
* 1.10 (20-Aug-1993) read_struct & write_struct added *
* 1.20 (22-Aug-1993) new endian routines added *
* 1.30 (23-Aug-1993) progess function added *
* 1.41 (13-Oct-1993) progess start & finish functions added *
* *
* (C) 1993 DEEJ Technology PLC *
* *
****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "io.h"
#ifndef ENDIAN_MACROS
/*
* little-endian to big-endian
*/
uint swap_endian(uint dword)
{
return( ((dword & 0xff000000)>>24) |
((dword & 0x00ff0000)>>8) |
((dword & 0x0000ff00)<<8) |
((dword & 0x000000ff)<<24) );
}
/*
* little-endian to big-endian for 16 bit words
*/
ushort swap_endian_word(ushort word)
{
return( ((ushort)(word & 0xff00)>>8) |
((ushort)(word & 0x00ff)<<8) );
}
/*
* swaps endian of DWORD/WORD if type doesnot match machine type
* type is LITTLE_ENDIAN (LE) or BIG_ENDIAN (BE)
*/
uint endian(int type, uint dword)
{
if(type != ENDIAN_TYPE)
return(swap_endian(dword));
else
return(dword);
}
ushort endian_w(int type, ushort word)
{
printf("endian_w in %02X\n",word);
if(type != ENDIAN_TYPE)
return(swap_endian_word(word));
else
return(word);
}
/*
* reverses bit fields in byte
*/
uint bit_swap(uint byte)
{
return( ((byte & 0x80)>>7) |
((byte & 0x40)>>5) |
((byte & 0x20)>>3) |
((byte & 0x10)>>1) |
((byte & 0x08)<<1) |
((byte & 0x04)<<3) |
((byte & 0x02)<<5) |
((byte & 0x01)<<7) );
}
uint bit2_swap(uint byte)
{
return( ((byte & 0xC0)>>6) |
((byte & 0x30)>>2) |
((byte & 0x0C)<<2) |
((byte & 0x03)<<6) );
}
uint bit4_swap(uint byte)
{
return( ((byte & 0xF0)>>4) |
((byte & 0x0F)<<4) );
}
#endif
/* put/get word little endian */
void fputwLE(ushort word, FILE *file)
{
word = endian_w(LE,word);
fwrite((char*)&word, sizeof(ushort), 1, file);
}
ushort fgetwLE(FILE *file)
{
ushort word;
word = endian_w(LE,word);
fread((char*)&word, sizeof(ushort), 1, file);
return(word);
}
/* put/get word big endian */
void fputwBE(ushort word, FILE *file)
{
word = endian_w(BE,word);
fwrite((char*)&word, sizeof(ushort), 1, file);
}
ushort fgetwBE(FILE *file)
{
ushort word;
word = endian_w(BE,word);
fread((char*)&word, sizeof(ushort), 1, file);
return(word);
}
/* put/get double word little endian */
void fputdLE(uint dword, FILE *file)
{
dword = endian(LE,dword);
fwrite((char*)&dword, sizeof(dword), 1, file);
}
uint fgetdLE(FILE *file)
{
uint dword;
dword = endian(LE,dword);
fread((char*)&dword, sizeof(dword), 1, file);
return(dword);
}
/* put/get word big endian */
void fputdBE(uint dword, FILE *file)
{
dword = endian(BE,dword);
fwrite((char*)&dword, sizeof(uint), 1, file);
}
uint fgetdBE(FILE *file)
{
uint dword;
dword = endian(BE,dword);
fread((char*)&dword, sizeof(uint), 1, file);
return(dword);
}
/*
* reads input, output & progress filenames from argv
* and opens streams in, out & err. If names are not
* given the streams default to stdin, stdout & stderr
*
* Can be used before arg processing if syntax is
* [-in <file>] [-out <file>] [-err <file>]. If so any parts
* found are removed from parameter list. If syntax is
* [<flags>...] [<infile> [<outfile> [<errfile]]], must be
* called after flags have been processed, and argc & argv
* ajusted to after the last flag.
*/
void file_args(int argc, char **argv, FILE **in, FILE **out, FILE **err)
{
char *infile, *outfile, *errfile;
int o_argc = argc;
char **o_argv = argv;
infile = outfile = errfile = 0;
argc--; argv++; /* skip program name */
/* look for -in, -out, -err <file> */
while(argc>0)
{
if(**argv=='-')
{
switch( (*argv)[1] )
{
case 'i':
if(strcmp(*argv, "-in")==0)
{
**argv = 0; /* clear flag from parameters */
argc--; argv++;
infile = *argv;
}
break;
case 'o':
if(strcmp(*argv, "-out")==0)
{
**argv = 0;
argc--; argv++;
outfile = *argv;
}
break;
case 'e':
if(strcmp(*argv, "-err")==0)
{
**argv = 0;
argc--; argv++;
errfile = *argv;
}
break;
default:
break;
}
}
/* next parameter */
argc--; argv++;
}
/* if no filenames found try alternate syntax */
if(infile==0 && outfile==0 && errfile==0)
{
if(o_argc>=2 && o_argv[1][0]!='-')
{
infile = o_argv[1];
if(o_argc>=3 && o_argv[2][0]!='-')
{
outfile = o_argv[2];
if(o_argc>=4 && o_argv[3][0]!='-')
errfile = o_argv[3];
}
}
}
if(infile == 0)
{
*in = stdin;
}
else
{
if((*in = fopen(infile,"r")) == NULL)
{
fprintf(stderr, "Unable to open input file %s\n",
infile);
exit(1);
}
*infile = 0; /* remove from parameter list */
}
if(outfile == 0)
{
*out = stdout;
}
else
{
if((*out = fopen(outfile,"w")) == NULL)
{
fprintf(stderr, "Unable to open output file %s\n",
outfile);
exit(2);
}
*outfile = 0; /* remove from parameter list */
}
if(errfile == 0)
{
*err = stderr;
}
else
{
/*
* open err file and ensure stderr from
* libraries uses it as well
*/
if((*err = freopen(errfile,"w",stderr)) == NULL)
{
/* dont use stderr as it will be closed */
fprintf(stdout, "Unable to open error file %s\n",
errfile);
exit(3);
}
/* set no buffering of stderr file */
setvbuf(*err, NULL, _IONBF, BUFSIZ);
*errfile = 0; /* remove from parameter list */
}
}
/*
* reads in a structure from a file
* correcting for endian'ness and arbitary alignment
*
* type : LITTLE_ENDIAN or BIG_ENDIAN
* buffer : structure cast to uchar*
* descrip : array of structure field sizes
* (1=byte, 2=word, 4=dword, >4=string, -1=end of table)
* file : file stream descriptor
*/
void read_struct(int type, BYTE *buffer, int *descrip, FILE *file)
{
WORD word;
DWORD dword;
while(*descrip != -1)
{
switch(*descrip)
{
case 1: /* byte */
*buffer++ = fgetc(file);
break;
case 2: /* word */
fread(&word, sizeof(WORD), 1, file);
word = endian_w(type,word);
buffer = (BYTE*)
(((int)buffer+ALIGN_WORD-1) & ~(ALIGN_WORD-1));
memcpy(buffer, (char*)&word, sizeof(WORD));
buffer += sizeof(WORD);
break;
case 4: /* double word */
fread(&dword, sizeof(DWORD), 1, file);
dword = endian(type,dword);
buffer = (BYTE*)
(((int)buffer+ALIGN_DWORD-1) & ~(ALIGN_DWORD-1));
memcpy(buffer, (char*)&dword, sizeof(DWORD));
buffer += sizeof(DWORD);
break;
default:
if(*descrip > 0)
{
fread(buffer, *descrip, 1, file);
buffer += *descrip;
}
break;
}
/* description pointer */
descrip++;
}
}
/*
* writes a structure to a file
* correcting for endian'ness and arbitary alignment
*/
void write_struct(int type, BYTE *buffer, int *descrip, FILE *file)
{
WORD word;
DWORD dword;
while(*descrip != -1)
{
switch(*descrip)
{
case 1: /* byte */
fputc(*buffer,file);
buffer++;
break;
case 2: /* word */
buffer = (BYTE*)
(((int)buffer+ALIGN_WORD-1) & ~(ALIGN_WORD-1));
memcpy((char*)&word, buffer, sizeof(WORD));
word = endian_w(type,word);
fwrite(&word, sizeof(WORD), 1, file);
buffer += sizeof(WORD);
break;
case 4: /* double word */
buffer = (BYTE*)
(((int)buffer+ALIGN_DWORD-1) & ~(ALIGN_DWORD-1));
memcpy((char*)&dword, buffer, sizeof(DWORD));
dword = endian(type,dword);
fwrite(&dword, sizeof(DWORD), 1, file);
buffer += sizeof(DWORD);
break;
default:
if(*descrip > 0)
{
fwrite(buffer, *descrip, 1, file);
buffer += *descrip;
}
break;
}
/* advance description pointer */
descrip++;
}
}
/*
* prints banner before calls to progress()
* string should not contain newline
*/
void progress_start(char *string)
{
fprintf(stderr, string);
progress(0,100);
}
/*
* displays progress of operation on stderr
* by printing dots every 2% of completion
* determined by value of current and max
*/
void progress(int current, int max)
{
static old_percent = 0;
int percent = (current*100)/max;
int i;
/* reset on for new progress indication */
if(percent < old_percent) old_percent = 0;
if(percent-old_percent>=2)
{
for(i=old_percent; i<percent; i+=2)
fputc('.', stderr);
old_percent = percent;
}
}
/*
* ensure display is correct after calls to progress()
*/
void progress_finish(void)
{
progress(100,100);
fprintf(stderr,"\n");
}